﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System
{
    /// <summary>
    /// 字符串扩展
    /// </summary>
    public static class StringExtensions
    {

        #region MyRegion

        /// <summary> 移除指定内容 </summary>
        public static string Remove(this string input, string removeStr)
        {
            return input.Replace(removeStr, string.Empty);
        }


        /// <summary>指示字符串的值是否是多个字符串中的一项</summary>
        /// <param name="input">输入文本</param>
        /// <param name="array">候选字符串</param>
        public static bool In(this string input, params string[] array)
        {
            for (int i = 0; i < array.Length; i++)
            {
                if (array[i].Equals(input))
                    return true;
            }
            return false;
        }

        /// <summary>指示字符串的值是否是字符串中的一项</summary>
        /// <param name="input">输入文本</param>
        public static bool In(this string input, string str)
        {
            return str.Contains(input);
        }

        /// <summary>字符串首尾加入指定内容</summary>
        /// <param name="input">输入文本</param>
        /// <param name="str">首尾字符串</param>
        public static string Warp(this string input, string str = "'")
        {
            if (input.IsNullOrEmpty())
                return str + str;
            return string.Format("{1}{0}{1}", input, str);
        }

        /// <summary>字符串首尾加入指定内容</summary>
        /// <param name="input">输入文本</param>
        /// <param name="str">首尾字符串</param>
        public static string Warp(this string input, string leftStr, string rightStr)
        {
            if (input.IsNullOrEmpty())
                return leftStr + rightStr;
            return string.Format("{1}{0}{2}", input, leftStr, rightStr);
        }

        /// <summary>字符串数组拼接</summary>
        /// <param name="str">字符串数组</param>
        /// <param name="splitChar">分隔符</param>
        public static string Combine(this string[] str, char? splitChar = ',')
        {
            if (str == null || str.Length < 1)
                return String.Empty;
            var builder = new StringBuilder();
            for (int i = 0; i < str.Length; i++)
            {
                var s = str[i];
                if (i == str.Length - 1)
                    builder.Append(s);
                else
                    builder.Append(s + splitChar);
            }
            return builder.ToString();
        }

        /// <summary>截取文本的前的多个字符作为摘要</summary>
        /// <param name="input">输入文本</param>
        /// <param name="width">保留文本长度</param>
        public static string GetSummary(this string input, int width = 6)
        {
            if (input.IsNullOrEmpty())
                return string.Empty;
            return input.Length > width ? (input.Substring(0, width) + "...") : input;
        }

        /// <summary>定宽截取字符串</summary>
        /// <param name="width">中文宽度</param>
        /// <remarks>
        /// 如果原字符串宽度小于等于width则直接返回
        /// 否则返回以省略号为结尾的宽度为width的字符串
        /// </remarks>
        public static string Subwidth(this string input, int width = 6)
        {
            if (String.IsNullOrEmpty(input))
                return input;
            int curWidth = 0;
            int width2 = width * 2 - 3;
            for (int index = 0; index < input.Length; index++)
            {
                //当前字符宽度
                int charWidth = input[index] < 127 ? 1 : 2;
                //如果加上当前字符宽度超出排除省略号长度时进入2种情况判断
                if (curWidth + charWidth > width2)
                {
                    //情况1：剩下内容刚好可以放下，则返回原内容
                    int lastWitdh = 0;
                    string lastString = input.Substring(index);
                    for (int j = 0; j < lastString.Length; j++)
                    {
                        lastWitdh += lastString[j] < 127 ? 1 : 2;
                        if (j == lastString.Length - 1 && lastWitdh == width * 2 - curWidth)
                            return input;
                    }
                    //情况2：后面的内容放不下，用...代替
                    return input.Substring(0, index) + (curWidth < width2 ? "...." : "...");
                }
                curWidth += charWidth;
            }
            //情况3：宽度可以放下全部字符，返回原内容
            return input;
        }

        /// <summary>指示指定的字符串是 null 或是 System.String.Empty 字符串。</summary>
        /// <param name="input">要测试的字符串</param>
        /// <returns>如果 value 参数为 null 或空字符串 ("")，则为 true；否则为 false。</returns>
        public static bool IsNullOrEmpty(this string input, bool trim = false)
        {
            return input == null || String.IsNullOrEmpty(trim ? input.Trim() : input);
        }

        /// <summary>为满足条件的字符串提供替代值</summary>
        /// <param name="input">输入文本</param>
        /// <param name="equalString">比较值</param>
        /// <param name="insteadString">替代值</param>
        /// <returns>输入值与比较值相等则返回替代值，反之返回原字符串</returns>
        public static string Instead(this string input, string equalString, string insteadString)
        {
            return equalString.Equals(input) ? insteadString : input;
        }

        /// <summary>为null和空字符串提供替代值</summary>
        /// <param name="input">任意字符串</param>
        /// <param name="defaultString">字符串为null时返回defaultString</param>
        public static string Default(this string input, string defaultString = "")
        {
            return string.IsNullOrEmpty(input) ? defaultString : input;
        }

        public static string Repeat(this string str, int count)
        {
            string output = "";
            for (int i = 0; i < count; i++)
            {
                output += str;
            }
            return output;
        }
        #endregion

        /// <summary> 移除指定内容 </summary>
        public static string[] Remove(this string[] inputs, params string[] strings)
        {
            IList<string> strList = new List<string>(inputs.Length - strings.Length);
            foreach (var input in inputs)
            {
                foreach (var str in strings)
                {
                    if (input.Equals(str))
                        continue;
                    strList.Add(input);
                }
            }
            return strList.ToArray();
        }

        /// <summary>数组中字符串首尾加入指定内容</summary>
        /// <param name="input">输入文本</param>
        /// <param name="leftStr">首尾字符串</param>
        public static string[] Warp(this string[] input, string str = "'")
        {
            for (int i = 0; i < input.Length; i++)
            {
                input[i] = input[i].Warp(str);
            }
            return input;
        }

        /// <summary>数组中字符串首尾加入指定内容</summary>
        /// <param name="input">输入文本</param>
        /// <param name="str">首尾字符串</param>
        public static string[] Warp(this string[] input, string leftStr, string rightStr)
        {
            for (int i = 0; i < input.Length; i++)
            {
                input[i] = input[i].Warp(leftStr, rightStr);
            }
            return input;
        }

        public static string[] Add(this IEnumerable<string> input, IEnumerable<string> toAppend)
        {
            return input.Union(toAppend).ToArray();
        }

        public static string[] Add(this IEnumerable<string> input, string toAppend)
        {
            var list = input.ToList();
            list.Add(toAppend);
            return list.ToArray();
        }

        public static bool In(this IEnumerable<string> inputs, bool ignoreCase, params string[] strings)
        {
            foreach (var input in inputs)
            {
                var _input = ignoreCase ? input.ToLower() : input;
                foreach (var str in strings)
                {
                    var _str = ignoreCase ? str.ToLower() : str;
                    if (_input.Equals(_str))
                        return true;
                }
            }
            return false;
        }


        #region MyRegion

        /// <summary>转全角(SBC case)</summary>
        /// <param name="input">任意字符串</param>
        /// <returns>全角字符串</returns>
        ///<remarks>
        ///全角空格为12288，半角空格为32
        ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
        ///</remarks>
        public static string ToSBC(this string input)
        {
            //半角转全角：
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 32)
                {
                    c[i] = (char)12288;
                    continue;
                }
                if (c[i] < 127)
                    c[i] = (char)(c[i] + 65248);
            }
            return new string(c);
        }

        /// <summary>转半角(DBC case) </summary>
        /// <param name="input">任意字符串</param>
        /// <returns>半角字符串</returns>
        ///<remarks>
        ///全角空格为12288，半角空格为32
        ///其他字符半角(33-126)与全角(65281-65374)的对应关系是：均相差65248
        ///</remarks>
        public static string ToDBC(this string input)
        {
            char[] c = input.ToCharArray();
            for (int i = 0; i < c.Length; i++)
            {
                if (c[i] == 12288)
                {
                    c[i] = (char)32;
                    continue;
                }
                if (c[i] > 65280 && c[i] < 65375)
                    c[i] = (char)(c[i] - 65248);
            }
            return new string(c);
        }

        /// <summary>统计可转全角字符数</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static int CountDBC(this string input)
        {
            if (string.IsNullOrEmpty(input))
                return 0;
            int count = 0;
            for (int i = 0; i < input.Length; i++)
            {
                if (input[i] < 127)
                    i++;
            }
            return count;
        }

        /// <summary>统计可转半角字符数</summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static int CountSBC(this string input)
        {
            if (string.IsNullOrEmpty(input))
                return 0;
            int count = 0;
            for (int i = 0; i < input.Length; i++)
            {
                if (input[i] > 65280)
                    i++;
            }
            return count;
        }

        /// <summary>编号右侧填充0达到指定长度</summary>
        /// <param name="input">输入文本</param>
        /// <param name="width">编号格式长度</param>
        public static string PadLeftSeq(this string input, int width = 8)
        {
            return input.PadLeft(width, '0');
        }

        /// <summary>去除编号左边的0</summary>
        public static string RemovePadLeftSeq(this string input)
        {
            for (int i = 0; i <= input.Length; i++)
            {
                if (input[i] != '0')
                    return input.Substring(i);
                i++;
            }
            return input;
        }


        #endregion
    }

}